package com.qgs.secsgem.common.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qgs.secsgem.mq.entity.MQMessage;
import org.springframework.messaging.Message;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 1.在从OPC Server 中 读到变量，要把变量包装一下 传给前端
 * 2.如果有些 opc-server 变量类型并不是 ns-iden  而仅仅是 iden 那么需要调用initialNodeId 初始化节点
 *
 * */
public class CommonFunction {
    public static boolean isLinux() {
        return System.getProperty("os.name").toLowerCase().contains("linux");
    }

    public static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }

    public static String extractError(String as){
        String[] errMsgs = as.split(",");
            /*for(String i:errMsgs){
                System.err.println(i);
            }*/

        String[] s = errMsgs[errMsgs.length-2].split(":");
        String errStatus = s[s.length-1];
        return errStatus.split("=")[1];
    }

    public static void createDirIfNotExit(String url){
        File file =new File(url);
        //如果文件夹不存在则创建
        if  (!file.exists()  && !file.isDirectory())
        {
            System.out.println("//不存在");
            boolean mkdir = file.mkdir();
        }
    }

    /**
     * 用处：在从OPC Server 中 读到变量，要把变量包装一下 传给前端
     * 含义: 包装变量
     * 如果传入的是数组，，那么把这个Object 包装成List，如果不是数组，就直接原路返回
     * //注意 传入的Objec，必须dataValue.getValue().getValue()
     * */
    public static Object var(Object object){
        if(object.getClass().isArray()){
            List<Object> objects = Arrays.asList(object);
            return objects.get(0);
        }
        return object.toString();
    }


    public static Object var2String(Object object){
        if(object.getClass().isArray()){
            Object[] o = (Object[])object;
            String res = "";
            if(o.length>0){
                for(int i=0;i<o.length;i++){
                    if(i==o.length-1){
                        res += o[i].toString();
                    }else {
                        res += o[i].toString() +",";
                    }
                }
            }
            return res;
        }
        return object.toString();
    }


    /**
     * 字节流数据 ==》java对象(MQMessage)
     * @param message  MQ的message原始对象
     * @return
     */
    public static MQMessage parse(Message<?> message){
        byte[] bytes =(byte[]) message.getPayload();
        MQMessage mqMessage = JSONObject.parseObject(bytes, MQMessage.class);
        return mqMessage;
    }


    public static String unescapeJava(String str) throws IOException
    {
        Writer out = new StringWriter();
        if (str != null)
        {
            int sz = str.length();
            StringBuilder unicode = new StringBuilder(4);
            boolean hadSlash = false;
            boolean inUnicode = false;

            for (int i = 0; i < sz; ++i)
            {
                char ch = str.charAt(i);
                if (inUnicode)
                {
                    unicode.append(ch);
                    if (unicode.length() == 4)
                    {
                        try
                        {
                            int nfe = Integer.parseInt(unicode.toString(), 16);
                            out.write((char) nfe);
                            unicode.setLength(0);
                            inUnicode = false;
                            hadSlash = false;
                        }
                        catch (NumberFormatException var9)
                        {
                        }
                    }
                }
                else if (hadSlash)
                {
                    hadSlash = false;
                    switch (ch)
                    {
                        case '\"':
                            out.write(34);
                            break;
                        case '\'':
                            out.write(39);
                            break;
                        case '\\':
                            out.write(92);
                            break;
                        case 'b':
                            out.write(8);
                            break;
                        case 'f':
                            out.write(12);
                            break;
                        case 'n':
                            out.write(10);
                            break;
                        case 'r':
                            out.write(13);
                            break;
                        case 't':
                            out.write(9);
                            break;
                        case 'u':
                            inUnicode = true;
                            break;
                        default:
                            out.write(ch);
                    }
                }
                else if (ch == 92)
                {
                    hadSlash = true;
                }
                else
                {
                    out.write(ch);
                }
            }

            if (hadSlash)
            {
                out.write(92);
            }

        }
        return out.toString();
    }


    /**
     * 解析body
     * JSONObject对象 ==》java对象
     * @param body   body
     * @param clazz  ResponseBody、RequestBody 里面的body
     * @return
     */
    public static Object parseBody(Object body,Class<?> clazz){
        JSONObject jsonObject = (JSONObject) body;
        Object o = JSON.toJavaObject(jsonObject, clazz);
        return o;
    }

    /*
        type:
            1.返回的是这种格式：2021-08-16 15:00:05
            2.返回的是这种格式：20210816150021
     */
    public static String getNowDate(Integer type){
        if(type==1){
            return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }else {
            return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        }
    }

    /**
     *32位默认长度的uuid
     * (获取32位uuid)
     *
     * @return
     */
    public static  String getUUID()
    {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 获取指定长度的随机数
     * (获取指定长度uuid)
     *
     * @return
     */
    public static String getUUID(int len)
    {
        if(0 >= len)
        {
            return null;
        }

        String uuid = getUUID();
        StringBuffer str = new StringBuffer();

        for (int i = 0; i < len; i++)
        {
            str.append(uuid.charAt(i));
        }

        return str.toString();
    }



    /**
     * 将int转为高字节在前，低字节在后的byte数组（大端）
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }
    /**
     * 将int转为低字节在前，高字节在后的byte数组（小端）
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }


    /**
     * byte数组到int的转换(小端)
     * @param bytes
     * @return
     */
    public static int bytes2IntLittle(byte[] bytes )
    {
        int int1=bytes[0]&0xff;
        int int2=(bytes[1]&0xff)<<8;
        int int3=(bytes[2]&0xff)<<16;
        int int4=(bytes[3]&0xff)<<24;

        return int1|int2|int3|int4;
    }
    /**
     * byte数组到int的转换(大端)
     * @param bytes
     * @return
     */
    public static int bytes2IntBig(byte[] bytes )
    {
        int int1=bytes[3]&0xff;
        int int2=(bytes[2]&0xff)<<8;
        int int3=(bytes[1]&0xff)<<16;
        int int4=(bytes[0]&0xff)<<24;

        return int1|int2|int3|int4;
    }
    /**
     * 将short转为高字节在前，低字节在后的byte数组（大端）
     * @param n short
     * @return byte[]
     */
    public static byte[] shortToByteBig(short n) {
        byte[] b = new byte[2];
        b[1] = (byte) (n & 0xff);
        b[0] = (byte) (n >> 8 & 0xff);
        return b;
    }

    /**
     * 将short转为低字节在前，高字节在后的byte数组(小端)
     * @param n short
     * @return byte[]
     */
    public static byte[] shortToByteLittle(short n) {
        byte[] b = new byte[2];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        return b;
    }
    /**
     *  读取小端byte数组为short
     * @param b
     * @return
     */
    public static short byteToShortLittle(byte[] b) {
        return (short) (((b[1] << 8) | b[0] & 0xff));
    }
    /**
     *  读取大端byte数组为short
     * @param b
     * @return
     */
    public static short byteToShortBig(byte[] b) {
        return (short) (((b[0] << 8) | b[1] & 0xff));
    }
    /**
     * long类型转byte[] (大端)
     * @param n
     * @return
     */
    public static byte[] longToBytesBig(long n) {
        byte[] b = new byte[8];
        b[7] = (byte) (n & 0xff);
        b[6] = (byte) (n >> 8  & 0xff);
        b[5] = (byte) (n >> 16 & 0xff);
        b[4] = (byte) (n >> 24 & 0xff);
        b[3] = (byte) (n >> 32 & 0xff);
        b[2] = (byte) (n >> 40 & 0xff);
        b[1] = (byte) (n >> 48 & 0xff);
        b[0] = (byte) (n >> 56 & 0xff);
        return b;
    }
    /**
     * long类型转byte[] (小端)
     * @param n
     * @return
     */
    public static byte[] longToBytesLittle(long n) {
        byte[] b = new byte[8];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8  & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        b[4] = (byte) (n >> 32 & 0xff);
        b[5] = (byte) (n >> 40 & 0xff);
        b[6] = (byte) (n >> 48 & 0xff);
        b[7] = (byte) (n >> 56 & 0xff);
        return b;
    }
    /**
     * byte[]转long类型(小端)
     * @param array
     * @return
     */
    public static long bytesToLongLittle( byte[] array )
    {
        return ((((long) array[ 0] & 0xff) << 0)
                | (((long) array[ 1] & 0xff) << 8)
                | (((long) array[ 2] & 0xff) << 16)
                | (((long) array[ 3] & 0xff) << 24)
                | (((long) array[ 4] & 0xff) << 32)
                | (((long) array[ 5] & 0xff) << 40)
                | (((long) array[ 6] & 0xff) << 48)
                | (((long) array[ 7] & 0xff) << 56));
    }

    /**
     * byte[]转long类型(大端)
     * @param array
     * @return
     */
    public static long bytesToLongBig( byte[] array )
    {
        return ((((long) array[ 0] & 0xff) << 56)
                | (((long) array[ 1] & 0xff) << 48)
                | (((long) array[ 2] & 0xff) << 40)
                | (((long) array[ 3] & 0xff) << 32)
                | (((long) array[ 4] & 0xff) << 24)
                | (((long) array[ 5] & 0xff) << 16)
                | (((long) array[ 6] & 0xff) << 8)
                | (((long) array[ 7] & 0xff) << 0));
    }


    /**
     * a 整除 b ，如果有余数+1
     * */
    public static Integer exactDivision(Integer a,Integer b) {
        int c = 0;
        if(a%b!=0){
            c = a/b+1;
        }
        return c;
    }

}
